package com.sos.controller;

import com.sos.exception.CustomException;
import com.sos.exception.ErrorCode;
import com.sos.model.dto.*;
import com.sos.model.vo.ResultVO;
import com.sos.service.UserService;
import com.sos.util.JwtUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.Map;


//查看swagger文档
//http://localhost:8080/api/swagger-ui.html

@RestController
@RequestMapping("/auth")
@RequiredArgsConstructor
@Slf4j
@Tag(name = "认证相关接口", description = "用户注册、登录和退出接口")
public class AuthController {

    private final UserService userService;
    private final JwtUtils jwtUtils;

    @PostMapping("/register")
    @Operation(summary = "用户注册", description = "用户注册接口，返回注册成功的用户信息")
    public ResultVO<UserResponseDTO> register(@Valid @RequestBody UserRegisterDTO registerDTO) {
        log.info("开始处理用户注册请求，参数：{}", registerDTO);
        return userService.register(registerDTO);
    }

    @PostMapping("/login")
    @Operation(summary = "用户登录", description = "用户登录接口，返回令牌和用户信息")
    public ResultVO<LoginResponseDTO> login(@Valid @RequestBody UserLoginDTO loginDTO) {
        log.info("开始处理用户登录请求，参数：{}", loginDTO);
        return userService.login(loginDTO);
    }

    @PostMapping("/logout")
    @Operation(summary = "用户退出登录", description = "清除当前用户的令牌和会话缓存")
// 关键：设置required = false，允许Authorization头缺失
    public ResultVO<?> logout(@RequestHeader(value = "Authorization", required = false) String authorizationHeader) {
        // 1. 处理Authorization头缺失的情况
        if (authorizationHeader == null || !authorizationHeader.startsWith("Bearer ")) {
            // 直接抛"未登录"异常，被全局处理器捕获后返回"请先登录"
            log.warn("退出登录时缺少有效的Authorization头");
            throw new CustomException(ErrorCode.NOT_LOGIN);
        }
        // 2. 正常提取Token并处理退出逻辑
        String token = authorizationHeader.substring(7);
        // 增加对token是否为空的判断
        if (token == null || token.isEmpty()) {
            log.warn("退出登录时提供了空的token");
            throw new CustomException(ErrorCode.NOT_LOGIN);
        }
        userService.logout(token);
        log.info("退出登录逻辑执行完成，准备返回响应");
        return ResultVO.success("退出登录成功");
    }
    
    @PostMapping("/refresh")
    @Operation(summary = "刷新访问令牌", description = "使用刷新令牌获取新的访问令牌和刷新令牌")
    @SecurityRequirement(name = "")
    public ResultVO<LoginResponseDTO> refresh(@Valid @RequestBody RefreshTokenDTO refreshTokenDTO) {
        log.info("开始处理刷新令牌请求");
        return userService.refreshToken(refreshTokenDTO);
    }
    
    @PostMapping("/forgot-password")
    @Operation(summary = "发送密码重置验证码", description = "向指定邮箱发送密码重置验证码")
    public ResultVO<?> sendPasswordResetCode(@Valid @RequestBody PasswordResetCodeRequestDTO requestDTO) {
        log.info("开始处理密码重置验证码请求，邮箱：{}", requestDTO.getEmail());
        userService.sendPasswordResetCode(requestDTO);
        return ResultVO.success("验证码已发送到邮箱，请注意查收");
    }

    @PostMapping("/reset-password")
    @Operation(summary = "验证验证码并重置密码", description = "使用验证码重置密码")
    public ResultVO<?> resetPassword(@Valid @RequestBody VerifyCodeResetPasswordDTO resetDTO) {
        log.info("开始处理密码重置请求，邮箱：{}", resetDTO.getEmail());
        userService.resetPassword(resetDTO);
        return ResultVO.success("密码重置成功");
    }
    
    // 添加一个测试端点来验证JWT Token
    @GetMapping("/verify-token")
    @Operation(summary = "验证JWT Token", description = "验证JWT Token是否有效")
    @SecurityRequirement(name = "")
    public ResultVO<Map<String, Object>> verifyToken(@RequestParam String token) {
        Map<String, Object> result = new java.util.HashMap<>();
        try {
            boolean isValid = jwtUtils.isTokenValid(token);
            result.put("valid", isValid);
            if (isValid) {
                String username = jwtUtils.getUsernameFromToken(token);
                result.put("username", username);
                result.put("message", "Token有效");
            } else {
                result.put("message", "Token无效或已过期");
            }
        } catch (Exception e) {
            result.put("valid", false);
            result.put("message", "Token验证异常: " + e.getMessage());
        }
        return ResultVO.success(result);
    }
}